/*
 * Amaze - QT downloader for the Amazon MP3 store
 * Copyright (c) 2010-2011 Robert Keevil
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <QDir>
#include <QFileInfo>
#include "download.h"

Download::Download(Amaze *parent) :
    QObject(parent)
{
    amaze = parent;
    request.setRawHeader("User-Agent", QString("%1 v%2")
                         .arg(AMAZE_NAME)
                         .arg(AMAZE_VERSION)
                         .toAscii());

    manager = new QNetworkAccessManager();

    connect(manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(get_finished()));
}

Download::~Download()
{

}

void Download::get_next()
{
    track_index = -1;
    amaze->mutex->lock();
    for (int i = 0; i < amaze->tracks->size(); i++)
    {
        // do we want to download this track...
        if (amaze->tracks->value(i).state == TRACK_NEW)
        {
            track_index = i;
            emit add_log(LOG_DEBUG, QString("Claiming index %1 to download")
                         .arg(i));
            break;
        }
    }
    amaze->mutex->unlock();

    if (track_index >= 0)
    {
        file = new QFile(amaze->tracks->value(track_index).filepath);
        QFileInfo info(file->fileName());
        QDir dir(info.absolutePath());
        if (!dir.exists())
        {
            QDir dir_make;
            if (!dir_make.mkpath(info.absolutePath()))
            {
                emit finished(track_index, false, tr("Unable to create folder %1")
                             .arg(info.absolutePath()));
                return;
            }
        }

        if (file->exists())
        {
            emit finished(track_index, false, tr("File %1 already exists")
                         .arg(file->fileName()));
            return;
        }

        if (!file->open(QIODevice::WriteOnly))
        {
            emit finished(track_index, false,
                         tr("Unable to open %1 for writing (permission error?)")
                         .arg(file->fileName()));
            return;
        }

        // The URL from the .amz XML is already url-encoded.
        // make sure we don't encode it again (as request.setUrl would do).
        url = QUrl::fromEncoded(amaze->tracks->value(track_index).url.toAscii());
        request.setUrl(url);

        reply = manager->get(request);
        connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
                this, SLOT(get_progress(qint64,qint64)));

        emit add_log(LOG_DEBUG, QString("Starting download of track %1")
                     .arg(track_index));
        emit started(track_index);
    }
    else
    {
        emit add_log(LOG_INFO, QString("No more tracks to download"));
    }
}

void Download::get_finished()
{
    /*
    if ( reply->error() != QNetworkReply::NoError )
    {
        emit add_log(LOG_ERROR, tr("Download: Request failed: %2")
                     .arg(reply->errorString()));
        return;
    }
    */

    url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
    if (!url.isEmpty())
    {
        request.setUrl(url);
        reply = manager->get(request);
        connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
                this, SLOT(get_progress(qint64,qint64)));
        emit add_log(LOG_DEBUG, QString("HTTP redirect to %1")
                     .arg(url.toString()));
    }
    else
    {
        track tmp = amaze->tracks->at(track_index);
        if ( reply->error() != QNetworkReply::NoError )
        {
            emit add_log(LOG_ERROR, tr("Download: Request failed: %2")
                         .arg(reply->errorString()));
            tmp.state = TRACK_ERROR;
            amaze->tracks->replace(track_index, tmp);
            return;
        }
        qint64 filesize = amaze->tracks->value(track_index).filesize;
        qint64 written = file->write(reply->readAll());

        emit add_log(LOG_DEBUG, QString("%1 / %2").arg(written).arg(filesize));

        file->close();
        file->deleteLater();

        tmp.state = TRACK_SUCCESS;
        amaze->tracks->replace(track_index, tmp);

        
        if (filesize > 0)
        {
            if (written != filesize)
            {
                emit add_log(LOG_ERROR,
                             tr("Download failed - expected %1 bytes, received %2")
                             .arg(filesize).arg(written));
//                emit finished(track_index, false, "");
//                return;
            }
        }
        
        emit finished(track_index, true, "");
    }
}

void Download::get_progress(qint64 current, qint64 total)
{
    emit progress(track_index, current, total);
}
